#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setVisible(false);
    ui->pushButton_2->setVisible(false);
    ui->pushButton_3->setVisible(false);
    ui->pushButton_4->setVisible(false);
    ui->pushButton_5->setVisible(false);
    
    linemapSize=50;
    changeTimes=0;
    isExchange=false;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::produceMap(unsigned char map[], unsigned char rmap[], int size)
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    for(int i=0;i<size;i++)
    {
        int value=0;
        while(1){
            value=qrand()%size;
            int j=0;
            for(j=0;j<i;j++)
                if(map[j]==value)
                    break;
            if(j==i)
                break;
        }
        map[i]=value;
        rmap[value]=i;
    }
}

void MainWindow::produceMap(int map[], int size)
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    for(int i=0;i<size;i++)
    {
        int value=0;
        while(1){
            value=qrand()%size;
            int j=0;
            for(j=0;j<i;j++)
                if(map[j]==value)
                    break;
            if(j==i)
                break;
        }
        map[i]=value;
    }
}

void MainWindow::on_pushButton_clicked()
{
    uchar *data=pic.bits();
    int l=pic.byteCount();
    int step=l/(pic.width()*pic.height());
    for(int i=0;i<l;i+=step)
    {
        for(int j=0;j<step;j++)
        {
            if(j<3)
                data[i+j]=mapB[data[i+j]];
        }
    }
    changeTimes++;
    ui->label->setPixmap(QPixmap::fromImage(pic));
}

void MainWindow::exchangeLine(int line1,int line2)
{
    uchar *data=pic.bits();
    int step=pic.byteCount()/(pic.width()*pic.height());

    int offset1=step*line1*pic.width();
    int offset2=step*line2*pic.width();
    int length=step*pic.width();

    unsigned char temp;
    for(int i=0;i<length;i++)
    {
        temp=data[i+offset1];
        data[i+offset1]=data[i+offset2];
        data[i+offset2]=temp;
    }
}

void MainWindow::on_pushButton_2_clicked()
{
    uchar *data=pic.bits();
    int l=pic.byteCount();
    int step=l/(pic.width()*pic.height());
    ui->info->setText(QString::number(changeTimes));

    for(int c=changeTimes-1;c>=0;c--)
    {
        for(int i=0;i<l;i+=step)
        {
            for(int j=0;j<step;j++)
            {
                if(j<3)
                    data[i+j]=rmapB[data[i+j]];
            }
        }
    }

    changeTimes=0;
    ui->label->setPixmap(QPixmap::fromImage(pic));
}



void MainWindow::on_pushButton_3_clicked()
{
    if(changeTimes>0)
    {
        char mapData[1100]="";
        sprintf(mapData,"%d",rmapB[0]);
        for(int i=1;i<256;i++)
        {
            sprintf(mapData,"%s %d",mapData,rmapB[i]);
        }

        pic.setText("map",tr(mapData));
        pic.setText("times",QString::number(changeTimes));

        QStringList temp=imgname.split('.');
        lockname=temp.at(0)+tr("_lock.png");

    }
    else
    {
        pic.setText("map",tr(""));
        pic.setText("times",tr(""));

        QStringList temp=imgname.split('.');
        lockname=temp.at(0)+tr("_raw.png");
    }

    if(isExchange)
    {
        char linemapData[80960]="";
        sprintf(linemapData,"%d",linemap[0]);
        for(int i=1;i<linemapSize;i++)
        {
            sprintf(linemapData,"%s %d",linemapData,linemap[i]);
        }

        pic.setText("linemap",tr(linemapData));
        pic.setText("linemapSize",QString::number(linemapSize));

        QStringList temp=imgname.split('.');
        lockname=temp.at(0)+tr("_lock.png");
    }

    pic.save(lockname);
    ui->info->setText(tr("save image to ")+lockname);
}

void MainWindow::initData()
{
    QString mapData=pic.text("map");
    QStringList mapValue=mapData.split(' ');

    if(mapValue.size()<256)
        produceMap(mapB,rmapB,256);
    else{
        for(int i=0;i<256;i++)
        {
            rmapB[i]=mapValue.at(i).toInt();
            mapB[rmapB[i]]=i;
        }
    }

    QString times=pic.text("linemapSize");
    if(times.length()<1)
    {
        linemapSize=50;
        produceMap(linemap,linemapSize);
        isExchange=false;
    }
    else
    {
        isExchange=true;
        ui->pushButton_5->setText("BkLine");

        linemapSize=times.toInt();

        QString linemapData=pic.text("linemap");
        mapValue=linemapData.split(' ');

        cout <<mapValue.size()<<" "<<linemapSize<<endl;
        if(mapValue.size()<0)
            produceMap(linemap,linemapSize);
        else{
            for(int i=0;i<linemapSize;i++)
            {
                linemap[i]=mapValue.at(i).toInt();
            }
        }
    }

    times=pic.text("times");
    if(times.length()<1)
        changeTimes=0;
    else
        changeTimes=times.toInt();
    cout <<changeTimes<<endl;
}

void MainWindow::on_loadbtn_clicked()
{
    imgname=ui->input->text();
    QFileInfo file(imgname);
    if(file.exists()==false)
    {
        ui->label->setText(imgname+tr(" is not exist"));
        return ;
    }
    
    pic=QImage(imgname);
    if(pic.width()<1)
    {
        ui->label->setText(imgname+tr(" is not valid image"));
        return ;
    }
    initData();
    ui->label->resize(pic.width(),pic.height());
    ui->label->setPixmap(QPixmap::fromImage(pic));
            
    ui->pushButton->setVisible(true);
    ui->pushButton_2->setVisible(true);
    ui->pushButton_3->setVisible(true);
    ui->pushButton_4->setVisible(true);
    ui->pushButton_5->setVisible(true);
    ui->input->setVisible(false);
    ui->loadbtn->setVisible(false);
    
}

void MainWindow::on_input_returnPressed()
{
    on_loadbtn_clicked();
}

void MainWindow::on_pushButton_4_clicked()
{
    int temp=changeTimes;
    on_pushButton_2_clicked();

    produceMap(mapB,rmapB,256);
    for(int i=0;i<temp;i++)
        on_pushButton_clicked();
    ui->info->setText(tr("reset over"));
}

void MainWindow::exLine()
{
    int h=pic.height();
    int step=linemapSize*2;
    for(int i=0;i<h;i++)
    {
        int p=i%step;
        int offset=(i/step)*step;
        if(p<linemapSize&&(linemap[p]+offset+linemapSize)<h)
        {
            exchangeLine(i,linemap[p]+offset+linemapSize);
        }
    }
    ui->label->setPixmap(QPixmap::fromImage(pic));
}

void MainWindow::on_pushButton_5_clicked()
{
    if(!isExchange)
    {
        ui->pushButton_5->setText("BkLine");
        isExchange=true;
    }
    else
    {
        ui->pushButton_5->setText("ExLine");
        isExchange=false;
    }
    exLine();
}

void MainWindow::keyPressEvent(QKeyEvent *ev)
{
    if(ev->key()==Qt::Key_1&&!ev->isAutoRepeat())
    {
        if(isExchange)
            exLine();

        linemapSize+=10;
        if(linemapSize>4096)
            linemapSize=4096;
        produceMap(linemap,linemapSize);

        if(isExchange)
            exLine();
        ui->info->setText(tr("exline number: ")+QString::number(linemapSize));
    }
    else if(ev->key()==Qt::Key_2&&!ev->isAutoRepeat())
    {
        if(isExchange)
            exLine();

        linemapSize-=10;
        if(linemapSize<10)
            linemapSize=10;
        produceMap(linemap,linemapSize);

        if(isExchange)
            exLine();
        ui->info->setText(tr("exline number: ")+QString::number(linemapSize));
    }
}
